import { forwardRef, HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { PaginationQueryDto } from '../common/dto/pagination-query.dto';
import { LoginUserDto } from './dto/login-user.dto';
import { ValidationException } from '../common/interceptor/exceptionInterceptor';
import { AuthService } from '../auth/auth.service';
import * as bcrypt from 'bcrypt';
import * as svgCaptcha from 'svg-captcha'
import { Response } from 'express';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private readonly usersRepository: Repository<User>,
    @Inject(forwardRef(() => AuthService))
    private readonly authService: AuthService,
  ) {}

  async register(createUserDto: CreateUserDto, session: Record<string, any>) {
    if (!(createUserDto.code.toLocaleLowerCase() === session.code.toLocaleLowerCase())) {
      throw new ValidationException(['图型验证码错误'], HttpStatus.BAD_REQUEST);
    }
    if (createUserDto.email && !createUserDto.email.match(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/)) {
      throw new ValidationException(['邮箱格式不正确'], HttpStatus.BAD_REQUEST);
    }
    if (createUserDto.phone && !createUserDto.phone.match(/^\d{10,}$/)) {
      throw new ValidationException(['手机号格式不正确'], HttpStatus.BAD_REQUEST);
    }
    const user = this.usersRepository.create(createUserDto);
    const errorList: string[] = [];

    const hasUser = await this.usersRepository
      .createQueryBuilder('user')
      .orWhere(`user.username = :username`, { username: user.username })
      .orWhere(`user.email = :email`, { email: user.email })
      .orWhere(`user.phone = :phone`, { phone: user.phone })
      .getOne();

    if (hasUser?.username === user.username && hasUser?.username) {
      errorList.push('用户名已存在');
    }
    if (hasUser?.email === user.email && hasUser?.email) {
      errorList.push('邮箱已存在');
    }
    if (hasUser?.phone === user.phone && hasUser?.phone) {
      errorList.push('手机号已存在');
    }

    // 盐和密码加密生成哈希密码
    user.password = await bcrypt.hash(user.password, await bcrypt.genSalt());

    if (errorList.length > 0) throw new ValidationException(errorList, HttpStatus.BAD_REQUEST);
    const { password, ...result } = await this.usersRepository.save(user);
    return result;
  }

  findAll(paginationQuery: PaginationQueryDto) {
    const { page = 1, pageSize = 10 } = paginationQuery;
    return this.usersRepository.find({
      where: { isDeleted: false },
      skip: (page - 1) * pageSize,
      take: pageSize,
    });
  }

  async findOne(id: number) {
    const user = await this.usersRepository.findOne({ where: { id } });
    if (!user) throw new HttpException(`未找到用户 #${id}`, HttpStatus.NOT_FOUND);
    const { password, ...result } = user;
    return result;
  }

  async update(id: number, updateUserDto: UpdateUserDto) {
    const user = await this.usersRepository.preload({ id, ...updateUserDto });
    if (!user) throw new HttpException(`未找到用户 #${id}`, HttpStatus.NOT_FOUND);
    return this.usersRepository.save(user);
  }

  async remove(id: number) {
    const user = await this.usersRepository.findOneBy({ id });
    if (!user) throw new HttpException(`未找到用户 #${id}`, HttpStatus.NOT_FOUND);
    user.deleteTime = new Date();
    user.isDeleted = true;
    return this.usersRepository.save(user);
  }

  async login(loginUserDto: LoginUserDto) {
    const { username, password } = loginUserDto;
    const user = await this.usersRepository.createQueryBuilder('user').andWhere(`user.username = "${username}"`).orWhere(`user.email = "${username}"`).orWhere(`user.phone = "${username}"`).getOne();
    if (!user) throw new HttpException(`用户名或密码不正确`, HttpStatus.BAD_REQUEST);
    const isMatch = await bcrypt.compare(password, user.password);
    if (!isMatch) throw new HttpException(`用户名或密码不正确`, HttpStatus.BAD_REQUEST);
    const { token } = this.authService.login({
      username,
      id: String(user.id),
      role: user.role,
    });
    return { token };
  }

  async createCAPTCHA(res: Response, session: Record<string, any>){
    const captcha = svgCaptcha.create({
      size: 4, //验证码几个字符
      fontSize: 50, //字体大小
      width: 100, //宽度
      height: 34, //高度
      background: '#cc9966' //背景颜色
    })
    session["code"] = captcha.text
    res.set('Content-Type', 'image/svg+xml');
    res.send(captcha.data);
  }


}
